package ar.edu.uba.fi.jmit.monitorengine.core.rangeobserver;

import java.util.HashMap;
import java.util.Map;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.core.ConfigurationManager;
import ar.edu.uba.fi.jmit.monitorengine.core.monitor.AverageMethodTimeMonitor;
import ar.edu.uba.fi.jmit.monitorengine.mock.ConfigurationManagerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.MonitorEngineSenderMock;

public class AverageMethodTimeRangeObserverTestCase extends
		MonitorEngineTestCase {
	
	private AverageMethodTimeMonitor monitor;
	private MonitorEngineSenderMock monitorEngineSender;
	
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		monitor = new AverageMethodTimeMonitor();
		monitorEngineSender = new MonitorEngineSenderMock();
		ConfigurationManagerMock.useMockConfigurationManager();
		ConfigurationManagerMock.addMonitorApplication("testMonitor", "application");
		ConfigurationManagerMock.addMonitorType("testMonitor", "MethodTime");
		Map<String, String> monitorConfiguration = new HashMap<String, String>();
		monitorConfiguration.put("methodConfiguration.method.class", "some.package.SomeClas");
		monitorConfiguration.put("methodConfiguration.method.name", "someMethod");
		ConfigurationManager.getInstance().addConfiguration("testMonitor", monitorConfiguration);
		monitor.setMonitorEngineSender(new MonitorEngineSenderMock());//uses another one
		monitor.init(ConfigurationManager.getInstance().getConfiguration("testMonitor"));
	}
	
	public void testMaxBoundExceded() {
		AverageMethodTimeRangeObserver rangeObserver = new AverageMethodTimeRangeObserver();
		monitor.addRangeObserver(rangeObserver);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(null);
		monitor.execute(this.createEvent(60L));
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		monitor.execute(this.createEvent(120L));
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		monitor.execute(this.createEvent(120L));
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		monitor.execute(this.createEvent(120L));
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals(AverageMethodTimeRangeObserver.class.getName(), event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(105L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
		assertEquals("someMethod", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_MONITORED_METHOD)));
		assertEquals("some.package.SomeClas", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_MONITORED_CLASS)));
	}
	
	private Event createEvent(long methodTime) {
		Event event = new Event();
		event.setSource("testRange");
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "\"testMonitor\"");
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), "new java.util.Date()");
		event.addData("elapsed_time", methodTime);
		return event;
	}
}
